package com.dbg.utils;

import com.dbg.entity.Language;
import com.dbg.entity.ResultEntity;
import com.dbg.entity.ResultSet;
import com.dbg.entity.TestSet;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

public class DocxUtils {

    // 在代码文件列表中，将代码去除注释，并保存至docx文件中
    public static ResultEntity docxForCode(List<String> codeFileList, String savePath, String title, String version) throws IOException {
        List<Language> languages = JSONUtils.languagesList;
        List<String> patterns = JSONUtils.patternsList;

        XWPFDocument document = new XWPFDocument();

        // 设置文档封面  暂未解决问题（封面去除页码）
        XWPFParagraph titlePage = document.createParagraph();
        XWPFRun titleRun = titlePage.createRun();
        titleRun.setFontFamily("黑体");
        titleRun.setBold(true);
        titleRun.setFontSize(36);
        // 先来5个换行符
        titleRun.addCarriageReturn();
        titleRun.addCarriageReturn();
        titleRun.addCarriageReturn();
        titleRun.addCarriageReturn();
        titleRun.addCarriageReturn();
        // 继续设置封面
        titleRun.setText(title + version);
        titlePage.setAlignment(ParagraphAlignment.CENTER);
        // 再来个换行符
        titleRun.addCarriageReturn();
        // 封面第二段（源程序3个字）
        XWPFParagraph codePage = document.createParagraph();
        XWPFRun codeRun = titlePage.createRun();
        codeRun.setText("源程序");
        codeRun.setFontFamily("黑体");
        codeRun.setBold(true);
        codeRun.setFontSize(36);
        codePage.setAlignment(ParagraphAlignment.CENTER);
        // 插入换页符
        XWPFParagraph pageBreak = document.createParagraph();
        XWPFRun pageBreakRun = pageBreak.createRun();
        pageBreakRun.addBreak(BreakType.PAGE);

        // 加入代码方法
        addParagraph(document, codeFileList, languages, patterns);

        // 设置页码，从第1页开始计数，首页不同
        setHeaderWithPageNumbers(document);

        // 设置页边距（上下2cm）
        int marginInCM = 1;
        int marginInEMU = marginInCM * 567; // 2 cm to EMUs

        // 创建节并设置页边距
        CTDocument1 doc = document.getDocument();
        CTSectPr sectPr = doc.addNewBody().addNewSectPr();
        CTPageMar pageMar = sectPr.addNewPgMar();
        pageMar.setTop(marginInEMU);
        pageMar.setBottom(marginInEMU);

        // 保存文件
        try(FileOutputStream out = new FileOutputStream(savePath + "\\" + title + version + "源程序.docx");) {
            document.write(out);
        } catch (Exception e) {
            return ResultSet
                    .ERROR
                    .setMessage("msg", 1);
        }

        return ResultSet.SUCCESS;
    }

    public static void addParagraph(XWPFDocument document, List<String> codeFileList, List<Language> languages, List<String> patterns) throws IOException {
        // 遍历加入文档代码内容
        for (String codeFile : codeFileList) {
            String content = new String(Files.readAllBytes(Paths.get(codeFile)));
            content = TextUtils.removeComments(content, languages, patterns, FileUtils.getFileExtension(codeFile));

            // 遍历加入每行代码
            for (String line : content.split("\n")) {
                if (!line.trim().isEmpty()) {
                    XWPFParagraph paragraph = document.createParagraph();
                    XWPFRun run = paragraph.createRun();
                    run.setText(line);
                }
            }

        }
    }

    // 设置页码，上面代码太长了
    // 设置页眉中的页码，右上角，页码从第0页开始
    public static void setHeaderWithPageNumbers(XWPFDocument document) {
        // 设置不同的首页页眉
        XWPFHeaderFooterPolicy headerFooterPolicy = document.createHeaderFooterPolicy();
        headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);
        headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.FIRST);

        // 设置页码从0开始
        CTPageNumber pageNumber = document.getDocument().getBody().addNewSectPr().addNewPgNumType();
        pageNumber.setStart(BigInteger.valueOf(0));

        // 创建普通页眉（包含页码）
        XWPFHeader defaultHeader = headerFooterPolicy.createHeader(XWPFHeaderFooterPolicy.DEFAULT);
        XWPFParagraph defaultHeaderParagraph = defaultHeader.createParagraph();
        defaultHeaderParagraph.setAlignment(ParagraphAlignment.RIGHT);

        // 插入页码字段
        CTSimpleField fldSimple = defaultHeaderParagraph.getCTP().addNewFldSimple();
        fldSimple.setInstr("PAGE  \\* MERGEFORMAT");

        // 添加一个空白字符，以便页码与字段分开
        XWPFRun run = defaultHeaderParagraph.createRun();
        run.setText(" ");

        // 强制更新字段
        document.enforceUpdateFields();

    }

    public static void main(String[] args) throws IOException {
        Set<String> strings = TestSet.javaLanguageSet();
        HashMap<String, Integer> sortRule = TestSet.javaSortRule();
        List<String> strings1 = FileUtils.iterationFile("C:\\Users\\someo\\Desktop\\bs\\bs\\intelligent_job_system-master", strings, sortRule);
        DocxUtils.docxForCode(strings1, "C:\\Users\\someo\\Desktop\\软著\\33", "test", "v1.0");
    }

}
